using EIP.Base.Models.Entities.System;
using EIP.Base.Models.Resx;
using EIP.Common.Core.Context;
using EIP.Common.Extension;
using EIP.Common.Language.Resource;
using EIP.Common.Logic;
using EIP.Common.Models;
using EIP.Common.Models.Dtos;
using EIP.Common.Models.Paging;
using EIP.Common.Models.Tree;
using EIP.Common.Util;
using EIP.System.Logic.Permission.ILogic;
using EIP.System.Models.Dtos.MobileMenu;
using EIP.System.Models.Enums;
using EIP.System.Repository.IRepository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace EIP.System.Logic.Permission.Logic
{
    /// <summary>
    /// 移动端菜单
    /// </summary>
    public class SystemMobileMenuLogic : DapperAsyncLogic<SystemMobileMenu>, ISystemMobileMenuLogic
    {
        #region 构造函数

        private readonly ISystemMobileMenuRepository _systemMobileMenuRepository;
        private readonly ISystemPermissionLogic _systemPermissionLogic;
        public SystemMobileMenuLogic(ISystemMobileMenuRepository systemMobileMenuRepository,
            ISystemPermissionLogic systemPermissionLogic)
        {
            _systemPermissionLogic = systemPermissionLogic;
            _systemMobileMenuRepository = systemMobileMenuRepository;
        }

        #endregion

        #region 方法

        /// <summary>
        /// 根据状态为True的模块信息
        /// </summary>
        /// <returns></returns>
        public async Task<OperateStatus<IEnumerable<BaseTree>>> Tree()
        {
            return OperateStatus<IEnumerable<BaseTree>>.Success((await FindAllAsync()).OrderBy(o => o.OrderNo).MapToList<SystemMobileMenu,BaseTree>());
        }

        /// <summary>
        /// 根据状态为True的模块信息
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<SystemMobileMenu>> FindMeunuByPId(IdInput input)
        {
            return (await FindAllAsync(f => f.ParentId == input.Id)).OrderBy(o => o.OrderNo);
        }

        /// <summary>
        /// 保存模块
        /// </summary>
        /// <param name="menu">模块信息</param>
        /// <returns></returns>
        public async Task<OperateStatus> Save(SystemMobileMenu menu)
        {
            OperateStatus result = new OperateStatus();
            var mobileMenu = await FindAsync(f => f.MobileMenuId == menu.MobileMenuId);
            var currentUser = EipHttpContext.CurrentUser();
            if (mobileMenu == null)
            {
                menu.MobileMenuId = CombUtil.NewComb();
                menu.CreateTime = DateTime.Now;
                menu.CreateUserId = currentUser.UserId;
                menu.CreateUserName = currentUser.Name;
                menu.UpdateTime = DateTime.Now;
                menu.UpdateUserId = currentUser.UserId;
                menu.UpdateUserName = currentUser.Name;
                result = await InsertAsync(menu);
            }
            else
            {
                menu.Id = mobileMenu.Id;
                menu.CreateTime = mobileMenu.CreateTime;
                menu.CreateUserId = mobileMenu.CreateUserId;
                menu.CreateUserName = mobileMenu.CreateUserName;

                menu.UpdateTime = DateTime.Now;
                menu.UpdateUserId = currentUser.UserId;
                menu.UpdateUserName = currentUser.Name;
                result = await UpdateAsync(menu);
            }
            await GeneratingParentIds(menu);
            return result;
        }
        
        /// <summary>
        /// 批量生成代码
        /// </summary>
        /// <returns></returns>
        private async Task<OperateStatus> GeneratingParentIds(SystemMobileMenu menu)
        {
            OperateStatus operateStatus = new OperateStatus();
            try
            {
                var menus = (await FindAllAsync()).ToList();
                var menuFind = menus.FirstOrDefault(w => w.MobileMenuId == menu.ParentId);
                if (menuFind != null)
                {
                    menu.ParentIds = menuFind.ParentIds.IsNullOrEmpty()
                        ? menu.MobileMenuId.ToString()
                        : menuFind.ParentIds + "," + menu.MobileMenuId;
                    menu.ParentIdsName = menuFind.ParentIdsName.IsNullOrEmpty()
                        ? menu.Name
                        : menuFind.ParentIdsName + "/" + menu.Name;
                }
                else
                {
                    menu.ParentIds = menu.MobileMenuId.ToString();
                    menu.ParentIdsName = menu.Name;
                }
                await UpdateAsync(menu);
                await GeneratingParentIds(menu, menus);
            }
            catch (Exception ex)
            {
                operateStatus.Msg = ex.Message;
                return operateStatus;
            }
            operateStatus.Msg = Chs.Successful;
            operateStatus.Code = ResultCode.Success;
            return operateStatus;
        }

        /// <summary>
        /// 递归获取代码
        /// </summary>
        /// <param name="menu"></param>
        /// <param name="menus"></param>
        private async Task GeneratingParentIds(SystemMobileMenu menu, IList<SystemMobileMenu> menus)
        {
            string parentIds = menu.ParentIds;
            string parentIdsName = menu.ParentIdsName;
            var next = menus.Where(w => w.ParentId == menu.MobileMenuId).ToList();
            foreach (var m in next)
            {
                m.ParentIds = parentIds + "," + m.MobileMenuId;
                m.ParentIdsName = parentIdsName + "/" + m.Name;
                m.ParentName = menu.Name;
                await UpdateAsync(m);
                await GeneratingParentIds(m, menus);
            }
        }
        
        /// <summary>
        /// 删除模块及下级数据
        /// </summary>
        /// <param name="input">父级id</param>
        /// <returns></returns>
        public async Task<OperateStatus> Delete(IdInput<string> input)
        {
            var operateStatus = new OperateStatus();
            foreach (var item in input.Id.Split(','))
            {
                var mobileMenuId = Guid.Parse(item);
                //查看是否具有下级
                if ((await FindMeunuByPId(new IdInput
                {
                    Id = mobileMenuId
                })).Any())
                {
                    operateStatus.Code = ResultCode.Error;
                    operateStatus.Msg = ResourceSystem.具有下级项;
                }
                //查看该模块是否已被特性占用
                var privilegeAccess = EnumPrivilegeAccess.模块权限.ToShort();
                var permissions = await _systemPermissionLogic.FindAllAsync(f => f.PrivilegeAccess == privilegeAccess && f.PrivilegeAccessValue == Guid.Parse(item));
                if (permissions.Any())
                {
                    operateStatus.Code = ResultCode.Error;
                    operateStatus.Msg = ResourceSystem.已被赋予权限;

                }
                operateStatus = await DeleteAsync(d=>d.MobileMenuId== mobileMenuId);
            }
            return operateStatus;
        }

        /// <summary>
        /// 查询所有具有功能项的模块
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<BaseTree>> FindHaveMenuButtonPermissionMenu()
        {
            return (await FindAllAsync(f => f.HaveButtonPermission && !f.IsFreeze)).OrderBy(o => o.OrderNo).MapToList<SystemMobileMenu,BaseTree>();
        }

        /// <summary>
        /// 获取显示在模块列表上数据
        /// </summary>
        /// <returns></returns>
        public async Task<OperateStatus<PagedResults<SystemMobileMenuFindOutput>>> Find(SystemMobileMenuFindInput input)
        {
            return OperateStatus<PagedResults<SystemMobileMenuFindOutput>>.Success(await _systemMobileMenuRepository.Find(input));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus<SystemMobileMenu>> FindById(IdInput input)
        {
            return OperateStatus<SystemMobileMenu>.Success(await FindAsync(f => f.MobileMenuId == input.Id));
        }

        /// <summary>
        /// 是否具有模块权限
        /// </summary>
        /// <returns></returns>
        public async Task<OperateStatus> HaveMenuPermission(IdInput input)
        {
            var menu = await FindAsync(f => f.MobileMenuId == input.Id);
            menu.HaveMenuPermission = !menu.HaveMenuPermission;
            return await UpdateAsync(menu);
        }

        /// <summary>
        /// 是否具有数据权限
        /// </summary>
        /// <returns></returns>
        public async Task<OperateStatus> HaveDataPermission(IdInput input)
        {
            var menu = await FindAsync(f => f.MobileMenuId == input.Id);
            menu.HaveDataPermission = !menu.HaveDataPermission;
            return await UpdateAsync(menu);
        }

        /// <summary>
        /// 是否具有字段权限
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        public async Task<OperateStatus> HaveFieldPermission(IdInput input)
        {
            var menu = await FindAsync(f => f.MobileMenuId == input.Id);
            menu.HaveFieldPermission = !menu.HaveFieldPermission;
            return await UpdateAsync(menu);
        }

        /// <summary>
        /// 是否具有功能项权限
        /// </summary>
        /// <returns></returns>
        public async Task<OperateStatus> HaveButtonPermission(IdInput input)
        {
            var menu = await FindAsync(f => f.MobileMenuId == input.Id);
            menu.HaveButtonPermission = !menu.HaveButtonPermission;
            return await UpdateAsync(menu);
        }

        /// <summary>
        /// 冻结
        /// </summary>
        /// <returns></returns>
        public async Task<OperateStatus> IsFreeze(IdInput input)
        {
            var menu = await FindAsync(f => f.MobileMenuId == input.Id);
            menu.IsFreeze = !menu.IsFreeze;
            return await UpdateAsync(menu);
        }
        #endregion
    }
}
